home *** CD-ROM | disk | FTP | other *** search
/ PC go! 2018 January / PCgo 01-2018 CD-ROM Germany.iso / nw.pak / Unnamed File 004888.txt < prev    next >
Encoding:
Text File  |  2015-07-29  |  10.0 KB  |  330 lines

  1. // Copyright 2014 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4.  
  5. define('data_receiver', [
  6.     'device/serial/data_stream.mojom',
  7.     'device/serial/data_stream_serialization.mojom',
  8.     'mojo/public/js/core',
  9.     'mojo/public/js/router',
  10. ], function(dataStream, serialization, core, router) {
  11.   /**
  12.    * @module data_receiver
  13.    */
  14.  
  15.   /**
  16.    * A pending receive operation.
  17.    * @constructor
  18.    * @alias module:data_receiver~PendingReceive
  19.    * @private
  20.    */
  21.   function PendingReceive() {
  22.     /**
  23.      * The promise that will be resolved or rejected when this receive completes
  24.      * or fails, respectively.
  25.      * @type {!Promise.<ArrayBuffer>}
  26.      * @private
  27.      */
  28.     this.promise_ = new Promise(function(resolve, reject) {
  29.       /**
  30.        * The callback to call with the data received on success.
  31.        * @type {Function}
  32.        * @private
  33.        */
  34.       this.dataCallback_ = resolve;
  35.       /**
  36.        * The callback to call with the error on failure.
  37.        * @type {Function}
  38.        * @private
  39.        */
  40.       this.errorCallback_ = reject;
  41.     }.bind(this));
  42.   }
  43.  
  44.   /**
  45.    * Returns the promise that will be resolved when this operation completes or
  46.    * rejected if an error occurs.
  47.    * @return {Promise.<ArrayBuffer>} A promise to the data received.
  48.    */
  49.   PendingReceive.prototype.getPromise = function() {
  50.     return this.promise_;
  51.   };
  52.  
  53.   /**
  54.    * Dispatches received data to the promise returned by
  55.    * [getPromise]{@link module:data_receiver.PendingReceive#getPromise}.
  56.    * @param {!ArrayBuffer} data The data to dispatch.
  57.    */
  58.   PendingReceive.prototype.dispatchData = function(data) {
  59.     this.dataCallback_(data);
  60.   };
  61.  
  62.   /**
  63.    * Dispatches an error if the offset of the error has been reached.
  64.    * @param {!PendingReceiveError} error The error to dispatch.
  65.    * @param {number} bytesReceived The number of bytes that have been received.
  66.    */
  67.   PendingReceive.prototype.dispatchError = function(error) {
  68.     if (error.queuePosition > 0)
  69.       return false;
  70.  
  71.     var e = new Error();
  72.     e.error = error.error;
  73.     this.errorCallback_(e);
  74.     return true;
  75.   };
  76.  
  77.   /**
  78.    * Unconditionally dispatches an error.
  79.    * @param {number} error The error to dispatch.
  80.    */
  81.   PendingReceive.prototype.dispatchFatalError = function(error) {
  82.     var e = new Error();
  83.     e.error = error;
  84.     this.errorCallback_(e);
  85.   };
  86.  
  87.   /**
  88.    * A DataReceiver that receives data from a DataSource.
  89.    * @param {!MojoHandle} handle The handle to the DataSource.
  90.    * @param {number} bufferSize How large a buffer to use.
  91.    * @param {number} fatalErrorValue The receive error value to report in the
  92.    *     event of a fatal error.
  93.    * @constructor
  94.    * @alias module:data_receiver.DataReceiver
  95.    */
  96.   function DataReceiver(handle, bufferSize, fatalErrorValue) {
  97.     this.init_(handle, fatalErrorValue, 0, null, [], false);
  98.     this.source_.init(bufferSize);
  99.   }
  100.  
  101.   DataReceiver.prototype =
  102.       $Object.create(dataStream.DataSourceClient.stubClass.prototype);
  103.  
  104.   /**
  105.    * Closes this DataReceiver.
  106.    */
  107.   DataReceiver.prototype.close = function() {
  108.     if (this.shutDown_)
  109.       return;
  110.     this.shutDown_ = true;
  111.     this.router_.close();
  112.     if (this.receive_) {
  113.       this.receive_.dispatchFatalError(this.fatalErrorValue_);
  114.       this.receive_ = null;
  115.     }
  116.   };
  117.  
  118.   /**
  119.    * Initialize this DataReceiver.
  120.    * @param {!MojoHandle} source A handle to the DataSource
  121.    * @param {number} fatalErrorValue The error to dispatch in the event of a
  122.    *     fatal error.
  123.    * @param {number} bytesReceived The number of bytes already received.
  124.    * @param {PendingReceiveError} pendingError The pending error if there is
  125.    *     one.
  126.    * @param {!Array.<!ArrayBuffer>} pendingData Data received from the
  127.    *     DataSource not yet requested by the client.
  128.    * @param {boolean} paused Whether the DataSource is paused.
  129.    * @private
  130.    */
  131.   DataReceiver.prototype.init_ = function(source,
  132.                                           fatalErrorValue,
  133.                                           bytesReceived,
  134.                                           pendingError,
  135.                                           pendingData,
  136.                                           paused) {
  137.     /**
  138.      * The [Router]{@link module:mojo/public/js/router.Router} for the
  139.      * connection to the DataSource.
  140.      * @private
  141.      */
  142.     this.router_ = new router.Router(source);
  143.     /**
  144.      * The connection to the DataSource.
  145.      * @private
  146.      */
  147.     this.source_ = new dataStream.DataSource.proxyClass(this.router_);
  148.     this.router_.setIncomingReceiver(this);
  149.     /**
  150.      * The current receive operation.
  151.      * @type {module:data_receiver~PendingReceive}
  152.      * @private
  153.      */
  154.     this.receive_ = null;
  155.     /**
  156.      * The error to be dispatched in the event of a fatal error.
  157.      * @const {number}
  158.      * @private
  159.      */
  160.     this.fatalErrorValue_ = fatalErrorValue;
  161.     /**
  162.      * The pending error if there is one.
  163.      * @type {PendingReceiveError}
  164.      * @private
  165.      */
  166.     this.pendingError_ = pendingError;
  167.     /**
  168.      * Whether the DataSource is paused.
  169.      * @type {boolean}
  170.      * @private
  171.      */
  172.     this.paused_ = paused;
  173.     /**
  174.      * A queue of data that has been received from the DataSource, but not
  175.      * consumed by the client.
  176.      * @type {module:data_receiver~PendingData[]}
  177.      * @private
  178.      */
  179.     this.pendingDataBuffers_ = pendingData;
  180.     /**
  181.      * Whether this DataReceiver has shut down.
  182.      * @type {boolean}
  183.      * @private
  184.      */
  185.     this.shutDown_ = false;
  186.   };
  187.  
  188.   /**
  189.    * Serializes this DataReceiver.
  190.    * This will cancel a receive if one is in progress.
  191.    * @return {!Promise.<SerializedDataReceiver>} A promise that will resolve to
  192.    *     the serialization of this DataReceiver. If this DataReceiver has shut
  193.    *     down, the promise will resolve to null.
  194.    */
  195.   DataReceiver.prototype.serialize = function() {
  196.     if (this.shutDown_)
  197.       return Promise.resolve(null);
  198.  
  199.     if (this.receive_) {
  200.       this.receive_.dispatchFatalError(this.fatalErrorValue_);
  201.       this.receive_ = null;
  202.     }
  203.     var serialized = new serialization.SerializedDataReceiver();
  204.     serialized.source = this.router_.connector_.handle_;
  205.     serialized.fatal_error_value = this.fatalErrorValue_;
  206.     serialized.paused = this.paused_;
  207.     serialized.pending_error = this.pendingError_;
  208.     serialized.pending_data = [];
  209.     $Array.forEach(this.pendingDataBuffers_, function(buffer) {
  210.       serialized.pending_data.push(new Uint8Array(buffer));
  211.     });
  212.     this.router_.connector_.handle_ = null;
  213.     this.router_.close();
  214.     this.shutDown_ = true;
  215.     return Promise.resolve(serialized);
  216.   };
  217.  
  218.   /**
  219.    * Deserializes a SerializedDataReceiver.
  220.    * @param {SerializedDataReceiver} serialized The serialized DataReceiver.
  221.    * @return {!DataReceiver} The deserialized DataReceiver.
  222.    */
  223.   DataReceiver.deserialize = function(serialized) {
  224.     var receiver = $Object.create(DataReceiver.prototype);
  225.     receiver.deserialize_(serialized);
  226.     return receiver;
  227.   };
  228.  
  229.   /**
  230.    * Deserializes a SerializedDataReceiver into this DataReceiver.
  231.    * @param {SerializedDataReceiver} serialized The serialized DataReceiver.
  232.    * @private
  233.    */
  234.   DataReceiver.prototype.deserialize_ = function(serialized) {
  235.     if (!serialized) {
  236.       this.shutDown_ = true;
  237.       return;
  238.     }
  239.     var pendingData = [];
  240.     $Array.forEach(serialized.pending_data, function(data) {
  241.       var buffer = new Uint8Array(data.length);
  242.       buffer.set(data);
  243.       pendingData.push(buffer.buffer);
  244.     });
  245.     this.init_(serialized.source,
  246.                serialized.fatal_error_value,
  247.                serialized.bytes_received,
  248.                serialized.pending_error,
  249.                pendingData,
  250.                serialized.paused);
  251.   };
  252.  
  253.   /**
  254.    * Receive data from the DataSource.
  255.    * @return {Promise.<ArrayBuffer>} A promise to the received data. If an error
  256.    *     occurs, the promise will reject with an Error object with a property
  257.    *     error containing the error code.
  258.    * @throws Will throw if this has encountered a fatal error or another receive
  259.    *     is in progress.
  260.    */
  261.   DataReceiver.prototype.receive = function() {
  262.     if (this.shutDown_)
  263.       throw new Error('DataReceiver has been closed');
  264.     if (this.receive_)
  265.       throw new Error('Receive already in progress.');
  266.     var receive = new PendingReceive();
  267.     var promise = receive.getPromise();
  268.     if (this.pendingError_ &&
  269.         receive.dispatchError(this.pendingError_)) {
  270.       this.pendingError_ = null;
  271.       this.paused_ = true;
  272.       return promise;
  273.     }
  274.     if (this.paused_) {
  275.       this.source_.resume();
  276.       this.paused_ = false;
  277.     }
  278.     this.receive_ = receive;
  279.     this.dispatchData_();
  280.     return promise;
  281.   };
  282.  
  283.   DataReceiver.prototype.dispatchData_ = function() {
  284.     if (!this.receive_) {
  285.       this.close();
  286.       return;
  287.     }
  288.     if (this.pendingDataBuffers_.length) {
  289.       this.receive_.dispatchData(this.pendingDataBuffers_[0]);
  290.       this.source_.reportBytesReceived(this.pendingDataBuffers_[0].byteLength);
  291.       this.receive_ = null;
  292.       this.pendingDataBuffers_.shift();
  293.       if (this.pendingError_)
  294.         this.pendingError_.queuePosition--;
  295.     }
  296.   };
  297.  
  298.   /**
  299.    * Invoked by the DataSource when an error is encountered.
  300.    * @param {number} offset The location at which the error occurred.
  301.    * @param {number} error The error that occurred.
  302.    * @private
  303.    */
  304.   DataReceiver.prototype.onError = function(error) {
  305.     if (this.shutDown_)
  306.       return;
  307.  
  308.     var pendingError = new serialization.PendingReceiveError();
  309.     pendingError.error = error;
  310.     pendingError.queuePosition = this.pendingDataBuffers_.length;
  311.     if (this.receive_ && this.receive_.dispatchError(pendingError)) {
  312.       this.receive_ = null;
  313.       this.paused_ = true;
  314.       return;
  315.     }
  316.     this.pendingError_ = pendingError;
  317.   };
  318.  
  319.   DataReceiver.prototype.onData = function(data) {
  320.     var buffer = new ArrayBuffer(data.length);
  321.     var uintView = new Uint8Array(buffer);
  322.     uintView.set(data);
  323.     this.pendingDataBuffers_.push(buffer);
  324.     if (this.receive_)
  325.       this.dispatchData_();
  326.   };
  327.  
  328.   return {DataReceiver: DataReceiver};
  329. });
  330.